import json
import pandas as pd
import requests
from pyecharts import options as opts
from pyecharts.charts import *
from pyecharts.globals import ThemeType
import pyecharts.options as opts
import openpyxl
from lxml import etree
import dataMap

class WorldCOVID(object):
    #初始化中国地图数据
    def initChina(self):
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.13 Safari/537.36'
        }
        #url来自百度疫情数据
        url = 'https://voice.baidu.com/act/newpneumonia/newpneumonia/'
        response = requests.get(url = url, headers = headers)
        tree = etree.HTML(response.text)
        dict1 = tree.xpath('//script[@id="captain-config"]/text()')
        dict2 = json.loads(dict1[0])
        return dict2

    #初始化美国数据
    def initAmerica(self):
        #爬取数据的网址（腾讯新闻网实时更新）
        America_url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign'
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36'
            ,'referer': 'https://news.qq.com/'
        }
        #获取到json格式数据
        response = requests.get(url=America_url,headers = headers).json()
        #将json格式转换成字典
        data = json.loads(response['data'])

        #保存数据
        with open('./countryCSV/美国疫情.json','w') as f:
            #再将字典改成json格式
            f.write(json.dumps(data,indent=2,ensure_ascii=False))   #indent为格式空两格的操作

        #将数据保存到Excel
        with open('./countryCSV/美国疫情.json','r') as f:
            data = f.read()
        #将json格式保存为字典
        data = json.loads(data)

        #获取美国的疫情数据
        AmericaDict = data['foreignList'][0]

        #获取美国各州的疫情数据
        ProvinceList = AmericaDict['children']

        #保存美国总的疫情数据
        AmericaCityList = []
        AmericaTotal = {'更新截止时间':AmericaDict['date'],'province':'北美洲','州':'美国','累计确诊':AmericaDict['confirm'],'治愈':AmericaDict['heal'],'死亡':AmericaDict['dead']}
        AmericaCityList.append(AmericaTotal)

        #遍历美国各州
        for i in range(len(ProvinceList)):
            date = ProvinceList[i]['date']
            province_English = ProvinceList[i]['nameMap']
            province = ProvinceList[i]['name']
            dead = ProvinceList[i]['dead']
            heal = ProvinceList[i]['heal']
            confirm = ProvinceList[i]['confirm']
            city_list = {'更新截止时间':date,'province':province_English,'州':province,'累计确诊':confirm,'治愈':heal,'死亡':dead}
            AmericaCityList.append(city_list)

        #将json格式转换成DataFrame
        AmericaTotalData = pd.DataFrame(AmericaCityList)

        #保存至Excel文档
        AmericaTotalData.to_excel('COVID-19-America.xlsx',index=False,sheet_name='美国各州疫情数据')

#世界数据初始化
    def __init__(self):
        #url来自腾讯疫情数据
        self.url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign'
        self.countrysUrl = 'https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
        self.initAmerica()

    #获取世界数据
    def getData(self):
        request = requests.get(self.url).json()
        data = json.loads(request['data'])
        return data

    #全球累计确诊/治愈/死亡信息
    def globalCumulativeHistory(self, name):
        data = self.getData()
        newAddConfirmList = []
        print(data)
        for i in data:
            print(i)
        for item in data['globalDailyHistory'][:-1]:
            temp = {
                'date' : item['date'],
                name : item['all'][name]
            }
            newAddConfirmList.append(temp)
        dataFrame = pd.DataFrame(newAddConfirmList)
        line = (
            Line().add_xaxis(list(dataFrame['date']))
                    .add_yaxis(series_name = name, y_axis = list(dataFrame[name]))
                    .set_global_opts(
                        title_opts = opts.TitleOpts(title = '全球历史%s信息(不含中国)' % name),
                        datazoom_opts = opts.DataZoomOpts(
                            is_show = True,
                            is_realtime = True,#滑块拖动时是否更新视图
                            range_end = 80,#数据窗口范围结束时的百分比
                            range_start = 50
                        ),
                        tooltip_opts = opts.TooltipOpts(
                            is_show = True,
                            trigger = 'axis',#坐标轴触发类型，常用于柱状图和折线图
                            trigger_on = 'mousemove|click',#同时移动鼠标和点击鼠标时触发
                        ),
            ).render('./templates/全球历史{}信息.html'.format(name))#保存为本地的html文件
        )

    #中国省份累计确诊病例示意图
    def chinaTotalData(self):
        data = self.initChina()
        workbook = openpyxl.Workbook()
        worksheet_China = workbook.active
        worksheet_China.title = "中国省份累计确诊病例示意图"
        worksheet_China.append([
            '省/直辖市/自治区/行政区', '现有确诊', '累计确诊', '累计治愈',
            '累计死亡', '现有确诊增量', '累计确诊增量',
            '累计治愈增量', '累计死亡增量'
        ])
        chinaData = data['component'][0]['caseList']
        for province in chinaData:#解析各省数据
            worksheet_China.append([
                province['area'],
                province['curConfirm'],
                province['confirmed'],
                province['crued'],
                province['died'],
                province['curConfirmRelative'],
                province['confirmedRelative'],
                province['curedRelative'],
                province['diedRelative']
            ])
        worksheet_City = workbook.create_sheet('中国城市疫情数据')
        worksheet_City.append([
            '城市',
            '现有确诊',
            '累计确诊',
            '累计治愈',
            '累计死亡',
            '累计确诊增量'
        ])

        for province in chinaData:
            for city in province['subList']:
                if 'curConfirm' not in city:#若城市无数据则用0替代
                    city['curConfirm'] = '0'
                if city['crued'] == '':
                    city['crued'] = '0'
                if city['died'] == '':
                    city['died'] = '0'
                worksheet_City.append([
                    city['city'],
                    '0',
                    city['confirmed'],
                    city['crued'],
                    city['died'],
                    city['confirmedRelative']
                ])

        timeDomestic = data['component'][0]['mapLastUpdatedTime']
        worksheet_Time = workbook.create_sheet('中国疫情数据更新时间')#创建一个工作表
        worksheet_Time.column_dimensions['A'].width = 22#设置列宽
        worksheet_Time.append(['中国疫情数据更新时间'])
        worksheet_Time.append([timeDomestic])

        workbook.save('COVID-19-China.xlsx')
        print("中国疫情数据已成功爬取并保存至COVID-19-China.xlsx！")

        page = Page(layout = Page.SimplePageLayout)
        page.add(
            dataMap.chinaTotalMap(),
        )
        page.render('./templates/中国省份累计确诊病例示意图.html')
        print("中国疫情可视化图表绘制成功！")

    #中国各省数据对比
    def compareChina(self):
        workbook = openpyxl.load_workbook('COVID-19-China.xlsx')
        worksheet_Data = workbook['中国省份累计确诊病例示意图']#获取文件中中国省份疫情数据表
        worksheet_Data.delete_rows(1)#删除第一行
        province = []#省份
        curconfirm = []#累计确诊
        curheal = []#累计治愈
        curdead = []#累计死亡
        for data in worksheet_Data.values:
            province.append(data[0])
            curconfirm.append(data[2])
            curheal.append(data[3])
            curdead.append(data[4])

        linesChina = (
            Line()
                .add_xaxis([
                    x for x in province
                    #'累计确诊', x_axis = list(curconfirm[1:])
                ])
                .add_yaxis('累计确诊', y_axis = list(curconfirm))
                .add_yaxis('累计治愈', y_axis = list(curheal))
                .add_yaxis('累计死亡', y_axis = list(curdead))
                .set_global_opts(
                    title_opts = opts.TitleOpts(title = '\n中国各省累计确诊、治愈、死亡病例折线图'),
                    datazoom_opts = opts.DataZoomOpts(
                        is_show = True,#显示
                        is_realtime = True,#拖动时，是否实时更新系列的视图。如果设置为 false，则只在拖拽结束的时候更新。
                        range_end = 60, #数据窗口范围的结束百分比。
                    ),
                    tooltip_opts = opts.TooltipOpts(
                        is_show = True,
                        trigger = 'axis', #坐标轴触发，主要在柱状图和折线图使用
                        trigger_on = 'mousemove|click', #同时鼠标移动和点击时触发。
                    ),
                )
                .render('./templates/中国各省数据对比.html')
        )

    #美国各州数据对比
    def compareAmerica(self):
        workbookAmerica = openpyxl.load_workbook('COVID-19-America.xlsx')
        worksheetAmerica_Data = workbookAmerica['美国各州疫情数据']
        worksheetAmerica_Data.delete_rows(1, 2)
        #worksheetAmerica_Data.delete_rows(2)
        provinceAmerica = []
        curconfirmAmerica = []
        curhealAmerica = []
        curdeadAmerica = []
        for data in worksheetAmerica_Data.values:
            provinceAmerica.append(data[2])
            curconfirmAmerica.append(data[3])
            curhealAmerica.append(data[4])
            curdeadAmerica.append([data[5]])

        linesAmerica = (
            Line()
                .add_xaxis([
                x for x in provinceAmerica
            ])
            .add_yaxis('累计确诊', y_axis = list(curconfirmAmerica))
            .add_yaxis('累计治愈', y_axis = list(curhealAmerica))
            .add_yaxis('累计死亡', y_axis = list(curdeadAmerica))
            .set_global_opts(
                title_opts = opts.TitleOpts(title = '\n美国各州累计确诊、治愈、死亡病例折线图'),
                datazoom_opts = opts.DataZoomOpts(
                    is_show = True,
                    is_realtime = True,
                    range_end = 60
                ),
                tooltip_opts = opts.TooltipOpts(
                    is_show = True,
                    trigger = 'axis',
                    trigger_on = 'mousemove|click',
                ),
            )
            .render('./templates/美国各州数据对比.html')
        )

    #今日各国新增确诊病例数量排名
    def countryAddConfirmRankList(self):
        data = self.getData()
        countryList = []
        for i in data['countryAddConfirmRankList']:
            temp = {
                'nation' : i['nation'],
                'addConfirm' : i['addConfirm']
            }
            countryList.append(temp)
        dataFrame = pd.DataFrame(countryList)

        #bar翻转x、y轴
        bar = (
            Bar()
            .add_xaxis(list(dataFrame['nation']))
            .add_yaxis('国家新增数量', list(dataFrame['addConfirm']))
            .reversal_axis()#翻转x、y轴
            .set_series_opts(label_opts = opts.LabelOpts(position = "right"))
            .set_global_opts(title_opts = opts.TitleOpts(title = "每日国家新增确诊病例数量排名"))
            .render("./templates/每日国家新增确诊病例数量排名.html")
        )

    #各洲累计确诊病例柱状图
    def contientData(self):
        data = self.getData()
        contientList = []
        for i in data['continentStatis'][1:]:
            try:
                temp = {
                    'date': i['date'],
                    '亚洲': i['statis']['亚洲'] if i['statis'].get('亚洲') else 0,
                    '其他': i['statis']['其他'] if i['statis'].get('其他') else 0,
                    '北美洲': i['statis']['北美洲'] if i['statis'].get('北美洲') else 0,
                    '大洋洲': i['statis']['大洋洲'] if i['statis'].get('大洋洲') else 0,
                    '欧洲': i['statis']['欧洲'] if i['statis'].get('欧洲') else 0,
                    '非洲': i['statis']['非洲'] if i['statis'].get('非洲') else 0,
                    '南美洲': i['statis']['南美洲'] if i['statis'].get('南美洲') else 0,
                }
                contientList.append(temp)
            except Exception as exception:
                print("发现异常：", exception)

        dataFrame = pd.DataFrame(contientList)

        barStack = (
            Bar()
            .add_xaxis(list(dataFrame['date']))
            .add_yaxis('亚洲', list(dataFrame['亚洲']), stack = 'stack1')
            .add_yaxis('其他', list(dataFrame['其他']), stack = 'stack1')
            .add_yaxis('北美洲', list(dataFrame['北美洲']), stack = 'stack1')
            .add_yaxis('大洋洲', list(dataFrame['大洋洲']), stack = 'stack1')
            .add_yaxis('欧洲', list(dataFrame['欧洲']), stack = 'stack1')
            .add_yaxis('南美洲', list(dataFrame['南美洲']), stack = 'stack1')
            .add_yaxis('海外现有确诊',[1718,6210,23190,67493,201196,503530])
            .set_series_opts(label_opts = opts.LabelOpts(is_show = False))
            .set_global_opts(
                title_opts = opts.TitleOpts(
                    title = "\n海外现有确诊及各洲累计确诊周比",
                ),
                tooltip_opts = opts.TooltipOpts(
                    is_show = True,
                    trigger = 'axis',#坐标轴触发类型，常用于柱状图和折线图
                    trigger_on = 'mousemove|click',#同时移动鼠标和点击鼠标时触发
                )
            )
            .render("./templates/各洲累计确诊病例柱状图.html")
        )

if __name__ == '__main__':
    worldCOVID = WorldCOVID()
    worldCOVID.chinaTotalData()#中国省份累计确诊病例示意图
    worldCOVID.contientData()#各洲累计确诊病例柱状图
    worldCOVID.countryAddConfirmRankList()#今日各国新增确诊病例数量排名